package com.bit.cfdi.web.vm;

import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.zkoss.bind.Validator;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;

import com.bit.cfdi.web.constants.CFDIConstants;
import com.bit.cfdi.web.development.utils.AutoLoginService;
import com.bit.cfdi.web.domain.Usuario;
import com.bit.cfdi.web.domain.UsuarioNegocio;
import com.bit.cfdi.web.services.LoginService;
import com.bit.cfdi.web.services.RegisterService;
import com.bit.cfdi.web.services.UsuarioNegocioService;
import com.bit.cfdi.web.services.UsuarioService;
import com.bit.cfdi.web.session.SessionUtils;
import com.bit.cfdi.web.validators.common.EmailValidator;
import com.bit.cfdi.web.validators.common.PasswordStrengthValidator;
import com.bit.cfdi.web.validators.login.EmailRegisterValidation;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class LoginViewModel {

	private Logger log = LogManager.getLogger(this.getClass().getName());
	
	//Spring autowired variables
	@WireVariable
	private UsuarioService usuarioService;
	@WireVariable
	private UsuarioNegocioService usuarioNegocioService;
	@WireVariable
	private RegisterService registerService;
	@WireVariable
	private LoginService loginService;
	@WireVariable
	private SessionUtils sessionUtils;
	@WireVariable
	private AutoLoginService autoLoginService;
	
	//Validators
	private EmailValidator usuarioLoginValidator;
	private EmailRegisterValidation emailRegistroValidator;
	private PasswordStrengthValidator passwordRegistroValidator;
	
	//Variables
	private String usuarioLogin;
	private String passwordLogin;
	private String emailRegistro;
	private String passwordRegistro;
	
	@Init
	public void init() {
		//Development Autologin
		if(autoLoginService.doAutoLogin()) {
			if(!autoLoginService.doAutoBusiness()) {
				Usuario usuario = (Usuario) sessionUtils
						.getFromSession(SessionUtils.USUARIO);
				List<UsuarioNegocio> usuarioNegocios = usuarioNegocioService
						.getNegociosFromUsuario(usuario);
				if(!usuarioNegocios.isEmpty()) {
					sessionUtils.addToSession(SessionUtils.NEGOCIO, 
							usuarioNegocios.get(0).getNegocio());
				}
			}
			Executions.getCurrent().sendRedirect(
					CFDIConstants.CFDIPages.HOME_URL);
			return;
		}
		//End Development Autologin
		usuarioLoginValidator = new EmailValidator("usuarioLogin");
		emailRegistroValidator = new EmailRegisterValidation("emailRegistro", 
				usuarioService);
		passwordRegistroValidator = new PasswordStrengthValidator(
				"passwordRegistro");
	}
	
	//Getters - Setters
	public String getUsuarioLogin() {
		return usuarioLogin;
	}
	
	public void setUsuarioLogin(final String usuarioLogin) {
		this.usuarioLogin = usuarioLogin;
	}
	
	public String getPasswordLogin() {
		return passwordLogin;
	}
	
	public void setPasswordLogin(final String passwordLogin) {
		this.passwordLogin = passwordLogin;
	}

	public String getEmailRegistro() {
		return emailRegistro;
	}

	public void setEmailRegistro(final String emailRegistro) {
		this.emailRegistro = emailRegistro;
	}

	public String getPasswordRegistro() {
		return passwordRegistro;
	}

	public void setPasswordRegistro(final String passwordRegistro) {
		this.passwordRegistro = passwordRegistro;
	}
	
	public Validator getUsuarioLoginValidator() {
		return usuarioLoginValidator;
	}
	
	public Validator getEmailRegistroValidator() {
		return emailRegistroValidator;
	}
	
	public Validator getPasswordRegistroValidator() {
		return passwordRegistroValidator;
	}
	
	//Commands
	@Command
	public void doLogin() {
		log.info("doLogin requested");
		Usuario usuario = loginService.performLogin(usuarioLogin, passwordLogin);
		if(usuario == null) {
			Messagebox.show(
					"Email o Password incorrecto",
					"Error",
					Messagebox.OK,
					Messagebox.ERROR);
			return;
		}
		if(sessionUtils.addToSession(SessionUtils.USUARIO, usuario)) {
			List<UsuarioNegocio> usuarioNegocios = usuarioNegocioService
					.getNegociosFromUsuario(usuario);
			if(!usuarioNegocios.isEmpty()) {
				sessionUtils.addToSession(SessionUtils.NEGOCIO, 
						usuarioNegocios.get(0).getNegocio());
			}
			Executions.getCurrent().sendRedirect(
					CFDIConstants.CFDIPages.HOME_URL);
		}
	}
	
	@Command
	public void doRegister() {
		log.info("doRegister requested");
		String codigoActivacion = null;
		try {
			codigoActivacion = registerService.doRegister(emailRegistro, 
					passwordRegistro);
		}catch(Exception ex) {
			Messagebox.show(
					"El usuario no pudo guardarse en el sistema",
					"Error",
					Messagebox.OK,
					Messagebox.ERROR);
			return;
		}
		try {
			registerService.sendRegistrationMail(emailRegistro, 
					passwordRegistro, codigoActivacion);
		}catch(Exception ex) {
			Messagebox.show(
					ex.getMessage(),
					"Error", 
					Messagebox.OK, 
					Messagebox.ERROR);
			return;
		}
		Executions.sendRedirect("activar.zul?email="+emailRegistro);
	}
}
